package com.youlian.utils.bitmap;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

import com.youlian.utils.FileHelper;
import com.youlian.utils.MyLog;
import com.youlian.utils.Utils;
import com.youlian.utils.YoulianApplication;
import com.youlian.utils.http.HTTPClientHelper;

/**
 * @author simon
 * @proName vipshop_1.6.0
 * @version 1.0
 * @Data 2012-11-8 下午02:54:50
 *
   <b>Comment...</b>
 */
public class ImageLoader {

	private int sampleSize=0;
	private	MemoryCache memoryCache = new MemoryCache();
	private	FileCache fileCache;
    private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
    // 线程池
    private	ExecutorService executorService;
    private int stub_id;

    /**
     *
     * @param context
     * @param samplesize
     * @param drawable_id
     */
    public ImageLoader(Context context,int samplesize,int drawable_id) {
    	this.sampleSize = samplesize;
    	stub_id = drawable_id;
        fileCache = new FileCache(context);
        executorService = Executors.newFixedThreadPool(5);
    }


    public boolean isDown=true;

    public void startDown(){
    	isDown = true;
    }
    public void stopDown(){
    	isDown = false;
    }


    // 当进入listview时默认的图片，可换成你自己的默认图片
    // 最主要的方法
    public void DisplayImage(String url, ImageView imageView,DownImageCallback callback) {
    	if(isDown){
    		imageViews.put(imageView, url);
            // 先从内存缓存中查找
            Bitmap bitmap = memoryCache.get(url);
            if (bitmap != null){
            	MyLog.error(getClass(), "************从内存缓存中取*****************");
                imageView.setImageBitmap(bitmap);

            }else{
                // 若没有的话则开启新线程加载图片
                queuePhoto(url, imageView,callback);
                imageView.setImageResource(stub_id);
            }
    	} else{
        	MyLog.error(getClass(), "************停止下载*****************");
    	}
    }

    public interface DownImageCallback {
        public void downCallback(String imageUrl,boolean status);
    }

//    /**
//     *
//     * @param down
//     */
//    public void addDownlaod(Download down) {
//    	if(isDown){
//    		imageViews.put(down.view, down.url);
//            // 先从内存缓存中查找
//            Bitmap bitmap = memoryCache.get(down.url);
//            if (bitmap != null){
//            	MyLog.error(getClass(), "************从内存缓存中取*****************");
//            	down.view.setImageBitmap(bitmap);
//            }else{
//                // 若没有的话则开启新线程加载图片
//                queuePhoto(down.url, down.view);
//                down.view.setImageResource(stub_id);
//            }
//    	} else{
//        	MyLog.error(getClass(), "************停止下载*****************");
//    	}
//    }

    private void queuePhoto(String url, ImageView imageView,DownImageCallback back) {
       PhotoToLoad p = new PhotoToLoad(url, imageView,back);
       executorService.submit(new PhotosLoader(p));
    }



    /**
     *
     * @param url
     * @return
     */
    private Bitmap getBitmap(String url) {
    	MyLog.error(getClass(), "****************Begin down Url:*******************:"+url);
    		//先从文件缓存中查找是否有
	        Bitmap b = decodeFile(url);
	        if (b != null){
	        	MyLog.error(getClass(), "****************从SD卡中取*******************");
	            return b;
	        }
            // 最后从指定的url中下载图片
            try {
        		Bitmap bitmap = null;
        		Bitmap cornerBmp = null;
            	byte[] bytes = Utils.openStream(HTTPClientHelper.getInputStream(url));
    			if (bytes!=null && bytes.length > 500) {
    				bitmap = BitmapUtils.getCorrectBmp(bytes, 0, Config.RGB_565);
    			}
    			if(sampleSize==0 && bitmap!=null){
    				FileHelper.saveFile(bitmap, url);
                	MyLog.error(getClass(), "****************下载成功*******************");
    				return bitmap;
    			}
    			if (bitmap != null) {
    				float scale = (float) (sampleSize) / bitmap.getWidth();
    				cornerBmp = BitmapUtils.getScaleBitmap(bitmap, scale);
    				if(bitmap!=cornerBmp && bitmap != null && !bitmap.isRecycled()) {
    					bitmap.recycle();
    					bitmap = null;
    				}
                	MyLog.error(getClass(), "****************下载成功*******************");
                	FileHelper.saveFile(cornerBmp, url);
    			}
    			return bitmap;
            } catch (Exception ex) {
                    ex.printStackTrace();
                    return null;
            }
    }

    	// decode这个图片并且按比例缩放以减少内存消耗，虚拟机对每张图片的缓存大小也是有限制的
    	private Bitmap decodeFile(String url) {
            	try {
            		File f = new File(YoulianApplication.cacheDir, FileHelper.getDownfileName(url));
            		if(!FileHelper.isExists(f)){
            			return null;
            		}
                    BitmapFactory.Options o2 = new BitmapFactory.Options();
                    o2.inSampleSize = 0;
                    Bitmap bitmap =  BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
                    Bitmap cornerBmp = null;
                    if (bitmap != null) {
        				float scale = (float) (sampleSize) / bitmap.getWidth();
        				cornerBmp = BitmapUtils.getScaleBitmap(bitmap, scale);
        				if(bitmap!=cornerBmp && bitmap != null && !bitmap.isRecycled()) {
        					bitmap.recycle();
        					bitmap = null;
        				}
        			}
                    return cornerBmp;
	            } catch (FileNotFoundException e) {
	            }
	            return null;
    	}

    // Task for the queue
    private class PhotoToLoad {
            public String url;
            public ImageView imageView;
            public DownImageCallback callback;

            public PhotoToLoad(String u, ImageView i,DownImageCallback back) {
                    url = u;
                    imageView = i;
                    callback = back;
            }
    }

   		class PhotosLoader implements Runnable {
	            PhotoToLoad photoToLoad;

	            PhotosLoader(PhotoToLoad photoToLoad) {
	                this.photoToLoad = photoToLoad;
	            }

	            @Override
	            public void run() {
                    if (imageViewReused(photoToLoad)){
                    	return;
                    }
                    Bitmap bmp = getBitmap(photoToLoad.url);
                    if(bmp!=null){
                        memoryCache.put(photoToLoad.url, bmp);
                    }
                    if (imageViewReused(photoToLoad))
                            return;
                    BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad,photoToLoad.url);
                    // 更新的操作放在UI线程中
                    Activity a = (Activity) photoToLoad.imageView.getContext();
                    a.runOnUiThread(bd);
	            }
   		}

    /**
     * 防止图片错位
     * @param photoToLoad
     * @return
     */
    boolean imageViewReused(PhotoToLoad photoToLoad) {
            String tag = imageViews.get(photoToLoad.imageView);
            if (tag == null || !tag.equals(photoToLoad.url))
                    return true;
            return false;
    }

    //用于在UI线程中更新界面
    class BitmapDisplayer implements Runnable {
    		String downUrl;
            Bitmap bitmap;
            PhotoToLoad photoToLoad;

            public BitmapDisplayer(Bitmap b, PhotoToLoad p,String url) {
                    bitmap = b;
                    photoToLoad = p;
                    downUrl = url;
            }

            public void run() {
                    if (imageViewReused(photoToLoad)){
                    	return;
                    }
                    if (bitmap != null){
                        photoToLoad.imageView.setImageBitmap(bitmap);
                    	photoToLoad.callback.downCallback(downUrl, true);
                    }else{
                        photoToLoad.imageView.setImageResource(stub_id);
                    	photoToLoad.callback.downCallback(downUrl, false);
                    }
            }
    }

    public void clearCache() {
            memoryCache.clear();
            fileCache.clear();
    }

    public static void CopyStream(InputStream is, OutputStream os) {
            final int buffer_size = 1024;
            try {
                    byte[] bytes = new byte[buffer_size];
                    for (;;) {
                            int count = is.read(bytes, 0, buffer_size);
                            if (count == -1)
                                    break;
                            os.write(bytes, 0, count);
                    }
            } catch (Exception ex) {
            }
    }
}
